import Flutter
import UIKit
import Foundation
import CoreText
import CoreGraphics

public class TextPixelPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    
    let channel = FlutterMethodChannel(name: "text_pixel", binaryMessenger: registrar.messenger())
    let instance = TextPixelPlugin()
    if let font = instance.registerFont(with: "new_song", size: 20) {
        print("Font registered and loaded: \(font)")
    } else {
        print("Font loading failed.")
    }
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "getPlatformVersion":
      result("iOS " + UIDevice.current.systemVersion)
    case "getTextColors":
        if let args = call.arguments as? Dictionary<String, Any>{
            if let textList = args["textList"] as? NSArray {
                let width = args["width"] as? CGFloat
                let height = args["height"] as? CGFloat
                let fontSize = args["fontSize"] as? CGFloat
                let maxFrames = args["maxFrames"] as? CGFloat
                let maxLines = args["maxLines"] as? CGFloat
                let continuousPaint = args["continuousPaint"] as? Bool
                let horizontalCenter = args["horizontalCenter"] as? Bool
                var newTextList = [TextBean]()
                textList.forEach { it in
                    if let element = it as? Dictionary<String, Any>{
                        let text = element["character"] as? String;
                        let color = element["colorValue"] as? Int;
                        if(text != nil && color != nil){
                            let bean = TextBean(text: text!, color: parseFlutterColor(color!))
                            newTextList.append(bean)
                        }
                    }
                }
                let fontName = "SimSun"
                guard let customFont = UIFont(name: fontName, size: fontSize!) else {
                    print("Failed to load custom font: \(fontName)")
                    return
                }
                let arr = preCalculate(textList: newTextList, font: customFont,
                fontSize: fontSize!, width: width!, maxLines: maxLines!, continuousPaint: continuousPaint!)
                let frames = min(ceil(arr[0] / width!), maxFrames!)
                print("frames \(frames)")
                print("totalWidth \(arr[0]) totalHeight \(arr[1])")
                let image = getCGImageFromText(textList: newTextList, font: customFont, fontSize: fontSize!, width: width! * frames, height: height!, totalWidth: arr[0], totalHeight: arr[1], frameWidth: width!, maxLines: maxLines!, continuousPaint: continuousPaint!, horizontalCenter: horizontalCenter!)
                let colors = getPixelColors(from: image!, frameWidth: Int(width!), frames: Int(frames))
                var map = Dictionary<String, Any>()
                map["colors"] = colors
                map["maxLines"] = Int(arr[1] / fontSize!)
                result(map)
            }else{
                result(nil)
            }
            result(nil)
          } else {
            result(FlutterError.init(code: "errorSetDebug", message: "data or format error", details: nil))
          }
    default:
      result(FlutterMethodNotImplemented)
    }
  }
    
    /// 获取绘制后的总宽度和总高度
    func preCalculate(textList:Array<TextBean>, font: UIFont, fontSize:CGFloat,
                      width: CGFloat, maxLines: CGFloat, continuousPaint: Bool) -> Array<CGFloat>{
        
        // 绘制的总宽度和总高度
        var totalWidth: CGFloat = 0
        var totalHeight: CGFloat = fontSize
        var frame: CGFloat = 1
        var line: CGFloat = 1
        var offsetX: CGFloat = 0
        for bean in textList{
            // 当前文字属性
            let style = NSMutableParagraphStyle()
            style.alignment = .left
            let attributes: [NSAttributedString.Key: Any] = [
                .font: font,
                .foregroundColor: bean.color,
                .paragraphStyle: style
            ]
            
            // 当前文字大小
            let textSize = (bean.text as NSString).size(withAttributes: attributes)
    
            let textWidth = textSize.width
            let limit = width * frame
            if(offsetX + textWidth > limit){
                if(line < maxLines){
                    offsetX = ((frame - 1) * width) + textWidth
                    line += 1
                    totalHeight = max(totalHeight, line * fontSize)
                }else{
                    if(continuousPaint && maxLines == 1){ // single line
                        offsetX += textWidth
                        totalWidth += textWidth
                    }else{
                        line = 1
                        let between = (width * frame) - offsetX
                        offsetX += between + textWidth
                        totalWidth += between + textWidth
                    }
                    
                    frame += 1
                }
            }else{
                offsetX += textWidth
                if(line == 1){
                    totalWidth += textWidth
                }
            }
        }
        
        return [totalWidth, totalHeight];
    }
    
    func preCalculateLineWidth(tempList: Array<TextBean>, width: CGFloat, font: UIFont) -> CGFloat{
        var sum: CGFloat = 0
        for item in tempList{
            let style = NSMutableParagraphStyle()
            style.alignment = .left
            let attributes: [NSAttributedString.Key: Any] = [
                .font: font,
                .foregroundColor: item.color,
                .paragraphStyle: style
            ]
            let textSize = (item.text as NSString).size(withAttributes: attributes)
            if(sum + textSize.width > width){ // overflow
                return sum
            }
            sum += textSize.width
        }
        return sum
    }
    
    
    func getCGImageFromText(textList: Array<TextBean>, font: UIFont, fontSize:CGFloat, width: CGFloat, height: CGFloat, totalWidth: CGFloat, totalHeight: CGFloat,
                            frameWidth: CGFloat,  maxLines: CGFloat,
                            continuousPaint: Bool, horizontalCenter: Bool
    ) -> CGImage? {
        let imageSize = CGSize(width: width, height: height)
        // 创建绘图上下文
        UIGraphicsBeginImageContextWithOptions(imageSize, false, 1.0)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        context.setShouldAntialias(false)
        context.setAllowsAntialiasing(false)
        
//        UIRectFill(CGRect(origin: .zero, size: imageSize))
        let startOffsetY = (height - totalHeight) / 2
        let length = textList.count
        
        var offsetX: CGFloat = 0
        
        // first line
        let lineWidth = preCalculateLineWidth(tempList: Array(textList[0..<length]), width: frameWidth, font: font)
        
        if(horizontalCenter && (lineWidth < frameWidth)){ // not full line width
           offsetX += (frameWidth - lineWidth) / 2
        }
        
        var offsetY: CGFloat = startOffsetY
        var frame: CGFloat = 1
        var line:CGFloat = 1
        var index:Int = 0
        for item in textList {
            let style = NSMutableParagraphStyle()
            style.alignment = .left
            let attributes: [NSAttributedString.Key: Any] = [
                .font: font,
                .foregroundColor: item.color,
                .paragraphStyle: style
            ]
            let textSize = (item.text as NSString).size(withAttributes: attributes)
            
            
            let textWidth = textSize.width
            let limit = frameWidth * frame
            if(offsetX + textWidth > limit){
                if(line < maxLines){
                    offsetX = (frame - 1) * frameWidth
                    
                    // next line
                    let lineWidth = preCalculateLineWidth(tempList: Array(textList[index..<length]), width: frameWidth, font: font)
                    
                    if(horizontalCenter && (lineWidth < frameWidth)){// not full line width
                        offsetX += (frameWidth - lineWidth) / 2
                    }
                    
                    
                    offsetY += fontSize

                    // 紧贴上一段文本效果
                    let textRect = CGRect(x: offsetX, y: offsetY + (textSize.height - font.lineHeight) / 2, width: textSize.width, height: font.lineHeight)
                    (item.text as NSString).draw(in: textRect, withAttributes: attributes)
                    
                    offsetX += textWidth
                    line += 1
                }else{// next frame
                    
                    if(continuousPaint && maxLines == 1){ // single line
                        // 紧贴上一段文本效果
                        let textRect = CGRect(x: offsetX, y: offsetY + (textSize.height - font.lineHeight) / 2, width: textSize.width, height: font.lineHeight)
                        (item.text as NSString).draw(in: textRect, withAttributes: attributes)
                        
                        offsetX += textWidth
                    }else{
                        line = 1
                        offsetY = startOffsetY
                        let between = (frameWidth * frame) - offsetX
                        offsetX += between
                        
                        // next frame first line
                        let lineWidth = preCalculateLineWidth(tempList: Array(textList[index..<length]), width: frameWidth, font: font)
                        
                        if(horizontalCenter && (lineWidth < frameWidth)){// not full line width
                            offsetX += (frameWidth - lineWidth) / 2
                        }
                        
                        // 紧贴上一段文本效果
                        let textRect = CGRect(x: offsetX, y: offsetY + (textSize.height - font.lineHeight) / 2, width: textSize.width, height: font.lineHeight)
                        (item.text as NSString).draw(in: textRect, withAttributes: attributes)
                        
                        offsetX += textWidth
                    }
                    
                    frame += 1
                }
            }else{
                
                // 紧贴上一段文本效果
                let textRect = CGRect(x: offsetX, y: offsetY + (textSize.height - font.lineHeight) / 2, width: textSize.width, height: font.lineHeight)
                (item.text as NSString).draw(in: textRect, withAttributes: attributes)
                
                offsetX += textWidth
            }
            
            // 换行效果
//            let textRect = CGRect(x: 0, y: offsetY + (textSize.height - font.lineHeight) / 2, width: textSize.width, height: font.lineHeight)
            
//            offsetX += textSize.width
//            offsetY += textSize.height
            index += 1
        }
        
        
        // 获取绘制的图片
        let image = UIGraphicsGetImageFromCurrentImageContext()
        
        // 结束上下文
        UIGraphicsEndImageContext()
        
        return image?.cgImage
    }
    
    /// 获取绘制后的图片
    func drawTextWithCoreGraphic(textList:Array<TextBean>,
                                 font: UIFont,
                                 width:Double, height:Double,
                                 totalWidth:Double, totalHeight:Double
    ) -> CGImage? {
        
        // 获取图像的宽度和高度
        let width = Int(width)
        let height = Int(height)
        print("width \(width) height \(height)")
        
        // 创建一个位图上下文
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitsPerComponent = 8
        let bytesPerRow = width * 4 // 每个像素4字节（RGBA）
        
        guard let context = CGContext(data: nil,
                                      width: width,
                                      height: height,
                                      bitsPerComponent: bitsPerComponent,
                                      bytesPerRow: bytesPerRow,
                                      space: colorSpace,
                                      bitmapInfo:CGImageAlphaInfo.premultipliedLast.rawValue) else{
            return nil
        }
        
        // 设置抗锯齿关
        context.setShouldAntialias(false)
        context.setAllowsAntialiasing(false)
        
        // 绘制文字
        var offsetX: CGFloat = 0
        for bean in textList{
            
            // 当前文字属性
            let attributes: [NSAttributedString.Key: Any] = [
                .font: font,
                .foregroundColor: bean.color
            ]
            
            // 当前文字大小
            let textSize = (bean.text as NSString).size(withAttributes: attributes)
            // 当前文字矩形
            let textRect = CGRect(x: offsetX, y: 0, width: textSize.width, height: textSize.height)
            
            // 绘制当前文字
//            (bean.text as NSString).draw(in: textRect, withAttributes: attributes)
            let attributedString = NSAttributedString(string: bean.text, attributes: attributes)
            let line = CTLineCreateWithAttributedString(attributedString)
            context.textMatrix = .identity // Reset text matrix
            context.textPosition = CGPoint(x: offsetX, y: 0) // Position the text
            // Draw the text in the context
            CTLineDraw(line, context)
            
            // 更新 offsetX 文字绘制 x 轴的起点
            offsetX += textSize.width
        }
        
        // 生成图片
        guard let image = context.makeImage() else{
            return nil
        }
        
        return image
    }

    /// 获取图片的像素颜色数据
    func getPixelData(from cgImage: CGImage) -> [Int]? {

        // 获取图像的宽度和高度
        let width = cgImage.width
        let height = cgImage.height
        
        // 创建一个位图上下文
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitsPerComponent = 8
        let bytesPerRow = width * 4 // 每个像素4字节（RGBA）
        
        // 创建上下文，分配内存用于存储像素数据
        guard let context = CGContext(data: nil,
                                      width: width,
                                      height: height,
                                      bitsPerComponent: bitsPerComponent,
                                      bytesPerRow: bytesPerRow,
                                      space: colorSpace,
                                      bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue),
              let pixelData = context.data else {
            return nil
        }
        
        // 将图像绘制到上下文中
        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
        
        // 获取指向像素数据的指针
        let buffer = pixelData.bindMemory(to: UInt8.self, capacity: width * height * 4)
        
        var colors: [Int] = Array(repeating: 0, count: width * height)
        var index = 0;

        // 遍历每个像素，读取其 RGBA 值
        for y in 0..<height {
            for x in 0..<width {
                let pixelIndex = (y * width + x) * 4
                
                let r = buffer[pixelIndex]
                let g = buffer[pixelIndex + 1]
                let b = buffer[pixelIndex + 2]
                let a = buffer[pixelIndex + 3]

                // 将 RGBA 值添加到结果数组中
                let colorA = ((Int(a) & 0xff) << 24)
                let colorR = ((Int(r) & 0xff) << 16)
                let colorG = ((Int(g) & 0xff) << 8)
                let colorB = ((Int(b) & 0xff) << 0)
                let colorValue = ( colorA | colorR | colorG | colorB) & 0xFFFFFFFF
                colors[index] = colorValue
                index += 1
            }
        }
        
        return colors
    }
    
    
    /// ---------------------------------------------------------
    ///
    ///
    ///
    /// ---------------------------------------------------------
    
    
    
    // Function to get pixel color data from UIImage
    func getPixelColors(from cgImage: CGImage, frameWidth: Int, frames:Int) -> [Int]? {
//        guard let cgImage = image.cgImage else { return nil }
        let info = cgImage.bitmapInfo
        let order = cgImage.byteOrderInfo
        let bytesPerRow = cgImage.bytesPerRow
        let width = cgImage.width
        let height = cgImage.height
        print("width \(width) height \(height) frameWidth \(frameWidth) frames \(frames)")
        var colors: [Int] = Array(repeating: 0, count: width * height)
        
        guard let dataProvider = cgImage.dataProvider,
                  let dataProviderData = dataProvider.data else { return nil }
            
            let data: UnsafePointer<UInt8> = CFDataGetBytePtr(dataProviderData)
        
//        guard let data = CFDataGetBytePtr(cgImage.dataProvider?.data) else { return nil }
        var index = 0;
//        var dataIndex = 0;
        for f in 0..<frames{
            for y in 0..<height {
                for x in (f * frameWidth)..<((f + 1) * frameWidth) {
                    
                   let dataIndex = ((width * y) + x) * 4
                   var r, g, b, a: UInt8

                   switch (order) {
                   case .order32Little:
                       // 获取每个像素的 RGBA 值（Little-endian顺序）
                       b = data[dataIndex]     // 蓝色（最低字节）
                       g = data[dataIndex + 1] // 绿色
                       r = data[dataIndex + 2] // 红色
                       a = data[dataIndex + 3] // Alpha（最高字节）
                   case .order32Big:
                       // 在 Big-endian 顺序，像素的存储顺序通常是 `0xAARRGGBB`
                       a = data[dataIndex]
                       r = data[dataIndex + 1]
                       g = data[dataIndex + 2]
                       b = data[dataIndex + 3]
                   default:
                       // TODO:: 请补充其他
                       r = data[dataIndex]
                       g = data[dataIndex + 1]
                       b = data[dataIndex + 2]
                       a = data[dataIndex + 3]
                   }

    //                let r = CGFloat(data[dataIndex]) / 255.0
    //                let g = CGFloat(data[dataIndex + 1]) / 255.0
    //                let b = CGFloat(data[dataIndex + 2]) / 255.0
    //                let a = CGFloat(data[dataIndex + 3]) / 255.0
    //                let color = UIColor(red: r, green: g, blue: b, alpha: a)
    //                print("color \(r) \(g) \(b) \(a)")
//                    print("x \(x) y \(y)")
                    let colorA = ((Int(a) & 0xff) << 24)
                    let colorR = ((Int(r) & 0xff) << 16)
                    let colorG = ((Int(g) & 0xff) << 8)
                    let colorB = ((Int(b) & 0xff) << 0)
                    let colorValue = ( colorA | colorR | colorG | colorB) & 0xFFFFFFFF
                    colors[index] = colorValue
                    index += 1
//                    dataIndex += 4
                }
            }
        }
        
        
        return colors
    }
    
    func drawTextOnSingleCanvas(text: String, font: UIFont, color: UIColor) -> UIImage? {
        let attributes: [NSAttributedString.Key: Any] = [
            .font: font,
            .foregroundColor: color
        ]
        
        // Measure total width and height needed for the entire text
        let totalSize = (text as NSString).size(withAttributes: attributes)
        
        // Create a single image context for the whole text
        UIGraphicsBeginImageContextWithOptions(totalSize, false, 0)
        defer { UIGraphicsEndImageContext() }
        
        var xPosition: CGFloat = 0
        
        for char in text {
            let charString = String(char)
            let attributedString = NSAttributedString(string: charString, attributes: attributes)
            let charSize = attributedString.size()
            
            // Draw each character at its position on the canvas
            attributedString.draw(at: CGPoint(x: xPosition, y: 0))
            xPosition += charSize.width
        }
        
        return UIGraphicsGetImageFromCurrentImageContext()
    }
    
    func getTextPixelColors(text: String, font: UIFont, colors: [(range: NSRange, color: UIColor)]) -> [[UIColor]]? {
        // Create an attributed string and apply colors to specific ranges
        let attributedText = NSMutableAttributedString(string: text)
        attributedText.addAttribute(.font, value: font, range: NSRange(location: 0, length: text.count))
        
        for colorRange in colors {
            attributedText.addAttribute(.foregroundColor, value: colorRange.color, range: colorRange.range)
        }
        
        // Calculate the text size
        let textSize = attributedText.size()
        let width = Int(textSize.width)
        let height = Int(textSize.height)
        
        // Create a bitmap-based graphics context
        UIGraphicsBeginImageContextWithOptions(textSize, false, 1.0)
        guard let context = UIGraphicsGetCurrentContext() else {
            UIGraphicsEndImageContext()
            return nil
        }
        
        // Draw the attributed text in the context
        attributedText.draw(at: CGPoint(x: 0, y: 0))
        
        // Get the image from the context
        guard let image = UIGraphicsGetImageFromCurrentImageContext(),
              let cgImage = image.cgImage else {
            UIGraphicsEndImageContext()
            return nil
        }
        
        UIGraphicsEndImageContext()
        
        // Prepare to read pixel data from the image
        guard let pixelData = cgImage.dataProvider?.data else { return nil }
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
        
        var pixelColors: [[UIColor]] = []
        
        // Loop through pixels
        for y in 0..<height {
            var rowColors: [UIColor] = []
            for x in 0..<width {
                let pixelIndex = ((width * y) + x) * 4
                let r = CGFloat(data[pixelIndex]) / 255.0
                let g = CGFloat(data[pixelIndex + 1]) / 255.0
                let b = CGFloat(data[pixelIndex + 2]) / 255.0
                let a = CGFloat(data[pixelIndex + 3]) / 255.0
                
                rowColors.append(UIColor(red: r, green: g, blue: b, alpha: a))
            }
            pixelColors.append(rowColors)
        }
        
        return pixelColors
    }

    func getTextPixelColors(text: String, font: UIFont, textColor: UIColor) -> [[UIColor]]? {
        // Set up the attributes for the text
        let attributes: [NSAttributedString.Key: Any] = [
            .font: font,
            .foregroundColor: textColor
        ]
        
        // Calculate the text size
        let textSize = (text as NSString).size(withAttributes: attributes)
        let width = Int(textSize.width)
        let height = Int(textSize.height)
        
        // Create a bitmap-based graphics context
        UIGraphicsBeginImageContextWithOptions(textSize, false, 1.0)
        guard let context = UIGraphicsGetCurrentContext() else {
            UIGraphicsEndImageContext()
            return nil
        }
        
        // Draw the text in the context
        (text as NSString).draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
        
        // Get the image from the context
        guard let image = UIGraphicsGetImageFromCurrentImageContext(),
              let cgImage = image.cgImage else {
            UIGraphicsEndImageContext()
            return nil
        }
        
        UIGraphicsEndImageContext()
        
        // Prepare to read pixel data from the image
        guard let pixelData = cgImage.dataProvider?.data else { return nil }
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
        
        var pixelColors: [[UIColor]] = []
        
        // Loop through pixels
        for y in 0..<height {
            var rowColors: [UIColor] = []
            for x in 0..<width {
                let pixelIndex = ((width * y) + x) * 4
                let r = CGFloat(data[pixelIndex]) / 255.0
                let g = CGFloat(data[pixelIndex + 1]) / 255.0
                let b = CGFloat(data[pixelIndex + 2]) / 255.0
                let a = CGFloat(data[pixelIndex + 3]) / 255.0
                
                rowColors.append(UIColor(red: r, green: g, blue: b, alpha: a))
            }
            pixelColors.append(rowColors)
        }
        
        return pixelColors
    }
    
    func parseFlutterColor(_ colorValue: Int) -> UIColor {
        // Extract the color components from the 32-bit integer
        let alpha = CGFloat((colorValue >> 24) & 0xFF) / 255.0
        let red = CGFloat((colorValue >> 16) & 0xFF) / 255.0
        let green = CGFloat((colorValue >> 8) & 0xFF) / 255.0
        let blue = CGFloat(colorValue & 0xFF) / 255.0
        
        // Return a UIColor with the extracted components
        return UIColor(red: red, green: green, blue: blue, alpha: alpha)
    }
    
   public func registerFont(with name: String, size: CGFloat) -> UIFont? {
       // Locate the font file in the bundle
       guard let fontURL = Bundle(for: TextPixelPlugin.self).url(forResource: name, withExtension: "ttc") else {
           print("Font file not found.")
           return nil
       }

//       // Register the font using Core Text
//       var error: Unmanaged<CFError>?
//       if !CTFontManagerRegisterFontsForURL(fontURL as CFURL, .process, &error) {
//           print("Failed to register font: \(String(describing: error?.takeRetainedValue()))")
//           return nil
//       }
       
       if let fontName = registerFontAndRetrieveName(from: fontURL) {
           print("Font registered with PostScript name: \(fontName)")
           // Verify by creating a UIFont using the exact PostScript name
           let fontDescriptor = UIFontDescriptor(name: fontName, size: size)
           let customFont = UIFont(descriptor: fontDescriptor, size: size)
           
           if customFont.familyName.isEmpty {
               print("Failed to load custom font with descriptor.")
               return nil
           }
           
           print("Custom font loaded successfully.")
           return customFont
       }else{
           return nil
       }

       
   }
    
   public func registerFontAndRetrieveName(from url: URL) -> String? {
        // Register the font
        var error: Unmanaged<CFError>?
        if !CTFontManagerRegisterFontsForURL(url as CFURL, .process, &error) {
            print("Failed to register font: \(String(describing: error?.takeRetainedValue()))")
            return nil
        }
        
        // Retrieve font descriptors
        guard let descriptors = CTFontManagerCreateFontDescriptorsFromURL(url as CFURL) as? [CTFontDescriptor],
              let firstDescriptor = descriptors.first else {
            print("No font descriptors found at URL.")
            return nil
        }
        
        // Retrieve the PostScript name from the font descriptor
        if let fontName = CTFontDescriptorCopyAttribute(firstDescriptor, kCTFontNameAttribute) as? String {
            print("Registered font name: \(fontName)")
            return fontName
        } else {
            print("Could not retrieve font name.")
            return nil
        }
    }
  
   public func registerCustomFont() {
       // Locate the plugin's bundle
       let bundle = Bundle(for: TextPixelPlugin.self)
       
       // Find the font file URL within the plugin bundle
       if let fontURL = bundle.url(forResource: "new_song", withExtension: "ttc") {
           var error: Unmanaged<CFError>?
           // Register the font with Core Text
           if !CTFontManagerRegisterFontsForURL(fontURL as CFURL, .process, &error) {
               print("Failed to register font: \(String(describing: error?.takeUnretainedValue()))")
           } else {
               print("Font registered successfully.")
           }
       } else {
           print("Font not found at expected path.")
       }
       
       let fontSize: CGFloat = 20.0

       // Set up the attributes for the font descriptor
       var attributes: [UIFontDescriptor.AttributeName: Any] = [:]
       attributes[.name] = "new_song" // Replace with your font's PostScript name

//       // Optional: Set a cascade list if you want a fallback font (e.g., system font)
//       let systemFont = UIFont.boldSystemFont(ofSize: fontSize)
//       attributes[.cascadeList] = [UIFontDescriptor(name: systemFont.fontName, size: fontSize)]

       // Create the UIFontDescriptor
       let fontDescriptor = UIFontDescriptor(fontAttributes: attributes)

       // Create the UIFont from the descriptor without optional binding
       let customFont = UIFont(descriptor: fontDescriptor, size: fontSize)

       // Now you can use `customFont`
       print("Custom font loaded successfully: \(customFont)")
    }
    
    func drawTextWithCoreGraphics(textList:Array<TextBean>, font: UIFont, width:Double, height:Double, totalWidth:Double, totalHeight:Double) -> CGImage? {
        print("width \(width) height \(height)")
        let size = CGSize(width: width, height: height)
        // Create a bitmap-based graphics context
//        UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
//        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        if let context = CGContext(data: nil,
                                      width: Int(width),
                                      height: Int(height),
                                      bitsPerComponent: 8,
                                      bytesPerRow: Int(width) * 4,
                                      space: CGColorSpaceCreateDeviceRGB(),
                                   bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) {
            // Flip the context to match UIKit's coordinate system
            context.setShouldAntialias(false)
            context.setAllowsAntialiasing(false)
//            context.saveGState(
//            context.translateBy(x: 0, y: height)
//            context.scaleBy(x: 1.0, y: -1.0)
            // Set the fill color to red
    //        context.setFillColor(UIColor.red.cgColor)
            // Fill the entire context with red
    //        context.fill(CGRect(origin: .zero, size: size))
            var offsetX: CGFloat = 0
            for bean in textList{
                // Attributes for rendering each character
                let attributes: [NSAttributedString.Key: Any] = [
                    .font: font,
                    .foregroundColor: bean.color
                ]
                // Calculate character size and draw it at the current x position
                let textSize = (bean.text as NSString).size(withAttributes: attributes)
                let textRect = CGRect(x: offsetX, y: 0, width: textSize.width, height: textSize.height)
                let attributedString = NSAttributedString(string: bean.text, attributes: attributes)
                // Create a line from attributed string
                let line = CTLineCreateWithAttributedString(attributedString)
                // Render the character into the context
//                (bean.text as NSString).draw(in: textRect, withAttributes: attributes)
                // Set up text matrix and position
                context.textMatrix = .identity // Reset text matrix
                context.textPosition = CGPoint(x: offsetX, y: 0) // Position the text
                // Draw the text in the context
                CTLineDraw(line, context)
                // Move xPosition forward by the character's width
                offsetX += textSize.width
                // Handle custom logic for each character's position here if needed
            }
//            context.restoreGState()
            // Retrieve the final image from the context
    //        let image = UIGraphicsGetImageFromCurrentImageContext()
    //        UIGraphicsEndImageContext()
            guard let image = context.makeImage() else{
                return nil;
            }
            return image
        }else { return nil }
    }
    
}
